﻿using System;
using System.Data;
using System.Data.Common;
using Microsoft.Data.SqlClient;

namespace MiniFox.Data.SqlServer
{
    /// <summary>
    /// 
    /// </summary>
    public class SqlServerDatabase : Database
    {
        internal const string PROVIDER_NAME = "Microsoft.Data.SqlClient";

        #region 构造
        /// <summary>
        /// 
        /// </summary>
        /// <param name="connectionString">数据库连接名</param>
        public SqlServerDatabase(string connectionString) : this(connectionString, PROVIDER_NAME)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="connectionString">数据库连接字符串</param>
        /// <param name="providerName">数据访问提供程序名称</param>
        public SqlServerDatabase(string connectionString, string providerName) : base(connectionString, providerName)
        {
        }

        #endregion
        /// <summary>
        /// 
        /// </summary>
        public override string ParameterPrefix
        {
            get { return "@"; }
        }
        /// <summary>
        /// 
        /// </summary>
        protected override DbProviderFactory CreateDbProviderFactory()
        {
            return SqlClientFactory.Instance;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cmdText"></param>
        /// <param name="cmdType"></param>
        /// <returns></returns>
        public override IDataCommand CreateDataCommand(string name, string cmdText, CommandType cmdType)
        {
            return new SqlServerDataCommand(name, cmdText, cmdType, this);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <returns></returns>
        public override IDataOperation<TEntity> CreateDataOperation<TEntity>()
        {
            return new SqlServerDataOperation<TEntity>(this);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <returns></returns>
        public override IDataQuery<TEntity> CreateDataQuery<TEntity>()
        {
            return new SqlServerDataQuery<TEntity>(this);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbParameter"></param>
        /// <param name="type"></param>
        protected override void SetParameterDbType(DbParameter dbParameter, Type type)
        {
            SqlDbType dbType;
            if (type == typeof(Boolean))
            {
                dbType = SqlDbType.Bit;
            }
            else if (type == typeof(Byte))
            {
                dbType = SqlDbType.TinyInt;
            }
            else if (type == typeof(SByte))
            {
                dbType = SqlDbType.TinyInt;
            }
            else if (type == typeof(Single))
            {
                dbType = SqlDbType.Real;
            }
            else if (type == typeof(Double))
            {
                dbType = SqlDbType.Float;
            }
            else if (type == typeof(Int16))
            {
                dbType = SqlDbType.SmallInt;
            }
            else if (type == typeof(UInt16))
            {
                dbType = SqlDbType.SmallInt;
            }
            else if (type == typeof(Int32))
            {
                dbType = SqlDbType.Int;
            }
            else if (type == typeof(UInt32))
            {
                dbType = SqlDbType.Int;
            }
            else if (type == typeof(Int64))
            {
                dbType = SqlDbType.BigInt;
            }
            else if (type == typeof(UInt64))
            {
                dbType = SqlDbType.BigInt;
            }
            else if (type == typeof(Char))
            {
                dbType = SqlDbType.Char;
            }
            else if (type == typeof(String))
            {
                dbType = SqlDbType.VarChar;
            }
            else if (type == typeof(Decimal))
            {
                dbType = SqlDbType.Decimal;
            }
            else if (type == typeof(DateTime))
            {
                dbType = SqlDbType.DateTime;
            }
            else if (type == typeof(DateTimeOffset))
            {
                dbType = SqlDbType.DateTimeOffset;
            }
            else if (type == typeof(Byte[]))
            {
                dbType = SqlDbType.Image;
            }
            else if (type == typeof(Guid))
            {
                dbType = SqlDbType.UniqueIdentifier;
            }
            else
            {
                dbType = SqlDbType.Variant;
            }
            ((SqlParameter)dbParameter).SqlDbType = dbType;
        }
    }
}
